package com.jxmcloud.business.cut.service.impl.logic;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jxmcloud.business.cut.dto.client.GetNextFlowInfoDto;
import com.jxmcloud.business.cut.dto.gm.UpdateProgressDto;
import com.jxmcloud.business.cut.json.DataConfigProgressLoader;
import com.jxmcloud.business.cut.model.database.DBUserAwardInfo;
import com.jxmcloud.business.cut.model.database.DBUserProgressLog;
import com.jxmcloud.business.cut.service.app.activity.IFlowInfoService;
import com.jxmcloud.business.cut.service.database.IUserAwardInfoDBService;
import com.jxmcloud.business.cut.service.database.IUserProgressLogDBService;
import com.jxmcloud.business.cut.service.logic.IGmOperatorHandle;
import com.jxmcloud.business.cut.vo.ProgressVo;
import com.jxmcloud.business.cut.vo.client.GetNextFlowInfoVo;
import com.jxmcloud.business.cut.vo.json.ConfigProgressVo;
import com.jxmcloud.business.cut.vo.user.PlayerInfoVo;
import com.jxmcloud.business.cut.vo.user.UserCashDetailItemVo;
import com.jxmcloud.business.cut.vo.user.UserCashDetailVo;
import com.jxmcloud.business.cut.vo.user.UserFlowVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class GmOperatorHandleImpl implements IGmOperatorHandle {
    @Autowired
    private IUserProgressLogDBService userProgressLogDBService;
    @Autowired
    private IUserAwardInfoDBService userAwardInfoDBService;
    @Autowired
    private IFlowInfoService flowInfoService;
    @Autowired
    private DataConfigProgressLoader dataConfigProgressLoader;

    @Override
    public boolean checkProcessParam(UpdateProgressDto updateProgressDto, PlayerInfoVo playerInfoVo) {
        //目的步骤
        Integer progressId = updateProgressDto.getProgressId();
        if (ObjectUtil.isNull(progressId) || progressId.equals(0)) {
            log.error("进度ID不能为空");
            return false;
        }
        String account = updateProgressDto.getAccount();
        if (ObjectUtil.isNull(account) || account.isEmpty()) {
            log.error("账号不能为空");
            return false;
        }

        UserFlowVo flowInfo = playerInfoVo.getFlowInfo();
        //用户当前步骤id
        Integer stepId = flowInfo.getStepId();
        if (Objects.equals(stepId, progressId)) {
            log.error("输入的步骤为当前步，请重新输入");
            return false;
        }
        return true;
    }

    @Override
    public ProgressVo handProgressBefore(List<DBUserProgressLog> userProgressLogs, Integer progressId, PlayerInfoVo playerInfoVo) {
        ProgressVo progressVo = new ProgressVo();
        UserCashDetailVo userCashDetailVo = playerInfoVo.getUserCashDetailVo();
        HashMap<Integer, UserCashDetailItemVo> progressList = userCashDetailVo.getProgressList();
        DBUserProgressLog dbUserProgressLog = userProgressLogs.get(0);


        // 查询设置流程之后的值
        QueryWrapper<DBUserProgressLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", playerInfoVo.getBase().getUid());
        queryWrapper.eq("activity_id", playerInfoVo.getActivity().getActivityId());
        queryWrapper.gt("id", dbUserProgressLog.getId()); // 新增ID大于条件，1000替换为实际阈值
        List<DBUserProgressLog> dbUserProgressLogs = userProgressLogDBService.getBaseMapper().selectList(queryWrapper);
        List<Integer> progressLogIds = dbUserProgressLogs.stream().map(DBUserProgressLog::getStepId).collect(Collectors.toList());

        // 删除play中的缓存
        for (DBUserProgressLog temp : dbUserProgressLogs) {
            Integer stepId = temp.getStepId();
            progressList.remove(stepId);
        }

        // 删除数据库中的领取信息
        QueryWrapper<DBUserAwardInfo> dbUserAwardInfoQueryWrapper = new QueryWrapper<>();
        dbUserAwardInfoQueryWrapper.eq("uid", playerInfoVo.getBase().getUid());
        dbUserAwardInfoQueryWrapper.eq("activity_id", playerInfoVo.getActivity().getActivityId());
        dbUserAwardInfoQueryWrapper.in("progress_id", progressLogIds);
        userAwardInfoDBService.remove(dbUserAwardInfoQueryWrapper);


        // 删除当前步骤之后的所有记录
        userProgressLogDBService.getBaseMapper().deleteBatchIds(dbUserProgressLogs);

        progressVo.setStepId(progressId);
        progressVo.setPreStepId(dbUserProgressLog.getParentStepId());
        return progressVo;
    }

    @Override
    public ProgressVo handProgressAfter(Integer progressId, PlayerInfoVo playerInfoVo) {
        ProgressVo progressVo = new ProgressVo();
        UserFlowVo flowInfo = playerInfoVo.getFlowInfo();
            List<DBUserProgressLog> userProgressLogByStepId = userProgressLogDBService
                    .getUserProgressLogByStepId(playerInfoVo.getBase().getUid(), playerInfoVo.getActivity().getActivityId(), null);

        for (DBUserProgressLog dbUserProgressLog : userProgressLogByStepId) {
            flowInfo.setStepId(dbUserProgressLog.getStepId());
            flowInfo.setPreId(dbUserProgressLog.getParentStepId());
            // 循环递归去调
            setUserProgress(progressId, playerInfoVo);
            if (playerInfoVo.getFlowInfo().getStepId().equals(progressId)) {
                break;
            }
        }

        progressVo.setStepId(flowInfo.getStepId());
        progressVo.setPreStepId(flowInfo.getPreId());
        return progressVo;
    }

    private void setUserProgress(Integer progressId, PlayerInfoVo playerInfoVo) {
        ConfigProgressVo configProgressVo = dataConfigProgressLoader.getConfigProgressMap().get(playerInfoVo.getFlowInfo().getStepId());
        // 合并所有事件数组
        Integer[] allEvents = Stream.of(
                configProgressVo.getStartEvent(),
                configProgressVo.getTimeEvent(),
                configProgressVo.getCloseEvent(),
                configProgressVo.getClickEvent(),
                configProgressVo.getShareEvent()
        ).filter(Objects::nonNull).flatMap(Arrays::stream).toArray(Integer[]::new);

        GetNextFlowInfoDto dto = new GetNextFlowInfoDto();
        dto.setCurStepId(playerInfoVo.getFlowInfo().getStepId());
        dto.setEventIds(allEvents);
        flowInfoService.getNextFlowInfo(dto, playerInfoVo);
        if (!progressId.equals(playerInfoVo.getFlowInfo().getStepId())) {
            setUserProgress(progressId, playerInfoVo);
        }
    }
}
